package cn.itsource.pethome.user.service.impl;

import cn.itsource.pethome.user.constant.PhoneConstant;
import cn.itsource.pethome.basic.service.impl.BaseServiceImpl;
import cn.itsource.pethome.basic.util.AjaxResult;
import cn.itsource.pethome.basic.util.MD5Utils;
import cn.itsource.pethome.basic.util.RedisUtils;
import cn.itsource.pethome.basic.util.StrUtils;
import cn.itsource.pethome.user.domain.User;
import cn.itsource.pethome.user.domain.dto.UserDto;
import cn.itsource.pethome.user.mapper.UserMapper;
import cn.itsource.pethome.user.service.IUserService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl extends BaseServiceImpl<User> implements IUserService {
    @Autowired
    private UserMapper userMapper;

    /**
     * 查询手机号
     *
     * @param phone
     * @return
     */
    @Override
    public AjaxResult checkPhone(String phone) {
        //根据手机号查询用户
        User user = userMapper.findUserByPhone(phone);
        if (user == null){
            return new AjaxResult();
        }
        return new AjaxResult(false,"该手机号已经被注册了，请登录");
    }
    /**
     * 检查前台传递过来的参数
     */
    public static void checkUser(UserDto userDto){
        //判断手机号
        if (StringUtils.isEmpty(userDto.getPassword())){
            throw new RuntimeException("手机号为空！");
        }
        //验证码
        if (StringUtils.isEmpty(userDto.getCode())) {
            throw new RuntimeException("验证码为空！");
        }
        //获取redis中存储的code  code:时间戳
        String redisCode = RedisUtils.INSTANCE.get(PhoneConstant.Phone_Reg + ":" + userDto.getPhone());
        if (redisCode == null){
            throw new RuntimeException("验证码失效，请重新获取！");
        }
        //获取redis中存储的code
        String code = redisCode.split(":")[0];
        //将code转化为大写进行比较
        if (!code.toUpperCase().equals(userDto.getCode().toUpperCase())){
            throw new RuntimeException("验证码错误！");
        }
        //密码
        if (StringUtils.isEmpty(userDto.getPassword())) {
            throw new RuntimeException("密码为空！");
        }
        //密码
        if (!userDto.getPassword().equals(userDto.getConfirmPassword())) {
            throw new RuntimeException("两次密码不一致！");
        }
    }

    /**
     * 将UserDto中的数据传递到User对象
     * @param userDto
     * @return
     */
    public User userDto2User(UserDto userDto){
        //创建User对象
        User user = new User();
        //将UserDto的属性值复制到user对象
        BeanUtils.copyProperties(userDto,user);
        //1、我们需要对密码进行加密和加盐
        //1、1首先我们获取10为随机数
        String salt = StrUtils.getComplexRandomString(10);
        //1、2对密码加密和加入随机产生的盐值
        String saltPassword = MD5Utils.encrypByMd5(user.getPassword() + salt);
        //1、3将盐值和密码,手机号注册状态设置为1，把用户名设置为手机号，重新设置进user对象，进行数据库保存
        user.setSalt(salt);
        user.setPassword(saltPassword);
        user.setState(PhoneConstant.ACTIVE);
        user.setUsername(user.getPhone());
        //返回对象
        return user;
    }
    /**
     * 用户注册
     *
     * @param userDto
     * @return
     */
    @Override
    @Transactional
    public void registerUser(UserDto userDto) {
        //检查参数验证
        checkUser(userDto);
        //将UserDto中的数据传递到User对象
        User user = userDto2User(userDto);
        //2、验证码正确，进行注册
        userMapper.addUser(user);
    }

    /**
     * 用户登录
     * @param username  用户名
     * @param password  密码
     * @return 返回user对象
     */
    @Override
    public User loginUser(String username, String password) {
        //判断用户名和密码是否为空
        if (StringUtils.isEmpty(username)) {
            throw new RuntimeException("用户名为空！");
        }
        //判断用户名和密码是否为空
        if (StringUtils.isEmpty(password)) {
            throw new RuntimeException("密码为空！");
        }

        //通过手机号获取到数据库中存放的对象数据
        User dbUser =  userMapper.loadUserByPhone(username);
        //判断用户名是否存在
        if (dbUser == null){
            throw new RuntimeException("用户名不存在！！");
        }else {
            //1、获取到该用户存储的盐值
            String salt = dbUser.getSalt();
            //3、进行MD5加密,返回通过输入密码加密后的密码
            String pwdSalt = MD5Utils.encrypByMd5(password+salt) ;
            //判断密码不正确
            if (!dbUser.getPassword().equals(pwdSalt) && !dbUser.getPassword().equals(password)) {
                throw new RuntimeException("密码不正确！！");
            }
        }
        //返回user对象
        return dbUser;
    }

    /**
     * 通过手机号发送code进行登录
     *  @param phone
     * @param code
     * @return
     */
    @Override
    public User loginByCode(String phone, String code) {
        //判断输入的手机号是否为空
        if (StringUtils.isEmpty(phone)) {
            throw new RuntimeException("手机号为空");
        }
        //判断输入的验证码是否为空
        if (StringUtils.isEmpty(code)) {
            throw new RuntimeException("验证码为空");
        }
        //通过手机号获取到数据库中存放的对象数据
        User dbUser =  userMapper.loadUserByPhone(phone);
        //判断用户名是否存在
        if (dbUser == null){
            throw new RuntimeException("用户名不存在！！");
        }else {
            //获取redis存储的验证码和时间戳
            String systemCode = RedisUtils.INSTANCE.get(PhoneConstant.Phone_Login + ":" + phone);
            if (systemCode != null){
                //获取redis中的验证码
                String RedisCode = systemCode.split(":")[0];
                if (!RedisCode.equals(code)){
                    throw new RuntimeException("验证码不正确！！");
                }
            }
        }
        return dbUser;
    }
}
